package project.ia04.agents.studio.GUICommunication;

import java.util.HashMap;


import project.ia04.agents.studio.StudioAgent;
import project.ia04.utils.Data;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.SequentialBehaviour;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class StepXSequentialBehaviour extends SequentialBehaviour {

	private int lvl = 0;
	private final String step;
	private String agentName;

	public class StepXInitBehaviour extends Behaviour {
		int state = 0;

		@Override
		public void action() {
			switch (this.state) {
			case 0:
				System.out
						.println("StudioAgent --> StepXInitBehaviour (Send \""
								+ StepXSequentialBehaviour.this.step
								+ "\")");
				final ACLMessage m = new ACLMessage(ACLMessage.REQUEST);
				m.setConversationId(StepXSequentialBehaviour.this.step);
				m.addReceiver(((StudioAgent)myAgent).getXAgent());
				this.myAgent.send(m);
				this.state++;
				break;
			case 1:
				final MessageTemplate template = MessageTemplate
						.and(MessageTemplate
								.MatchPerformative(ACLMessage.REQUEST),
								MessageTemplate
										.MatchConversationId(StepXSequentialBehaviour.this.step));
				final ACLMessage reponse = this.myAgent.receive(template);
				if (reponse != null) {
					System.out
							.println("StudioAgent --> StepXInitBehaviour (Reception \""
									+ StepXSequentialBehaviour.this.step
									+ "\")");
					StepXSequentialBehaviour.this.agentName = ((StudioAgent)myAgent).getFieldDeserialize(
							Data.STAFFNAME, reponse.getContent());
					// Get Agent Lvl :
					System.out
							.println("StudioAgent --> StepXInitBehaviour (Ask Lvl to StaffAgent \""
									+ StepXSequentialBehaviour.this.agentName
									+ "\" - \""
									+ StepXSequentialBehaviour.this.step
									+ "\")");
					final ACLMessage askLvl = new ACLMessage(
							ACLMessage.REQUEST);
					askLvl.setConversationId(Data.ASKLVL);
					askLvl.addReceiver(((StudioAgent)myAgent)
							.getStaffAgent(StepXSequentialBehaviour.this.agentName));
					this.myAgent.send(askLvl);
					this.state++;
				}
				break;
			case 2:
				final MessageTemplate templ = MessageTemplate.and(
						MessageTemplate
								.MatchPerformative(ACLMessage.INFORM),
						MessageTemplate.MatchConversationId(Data.ASKLVL));
				final ACLMessage response = this.myAgent.receive(templ);
				if (response != null) {
					System.out
							.println("StudioAgent --> StepXInitBehaviour (Reception from StaffAgent - \""
									+ StepXSequentialBehaviour.this.step
									+ "\"");
					StepXSequentialBehaviour.this.lvl = Integer
							.parseInt(response.getContent());
					this.state++;
				}
				break;
			}
		}

		@Override
		public boolean done() {
			return this.state == 3;
		}
	}

	public class StepExchangeBehaviour extends TickerBehaviour {

		private int count = 0;

		public StepExchangeBehaviour(final Agent a, final long time) {
			super(a, time);
		}

		@Override
		public void onTick() {
			if (this.count < (StepXSequentialBehaviour.this.lvl * 3)) {
				System.out.println("StepExchangeBehaviour --> Step ("+count+")");
				this.myAgent.addBehaviour(new AskItems2Agent());
				this.count++;
			} else {
				System.out.println("StepExchangeBehaviour --> End");
				final ACLMessage term = new ACLMessage(ACLMessage.INFORM);
				term.setConversationId(Data.CMDTERMINATE);
				term.addReceiver(((StudioAgent)myAgent).getXCommandAgent());
				this.myAgent.send(term);
				this.stop();
			}
		}

		public class AskItems2Agent extends Behaviour {

			private int state = 0;

			@Override
			public void action() {
				switch (this.state) {
				case 0:
					System.out
							.println("StudioAgent --> AskItems2Agent (Send AskItems to StaffAgents)");
					ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
					message.setConversationId(Data.GETITEMS);
					message.addReceiver(((StudioAgent)myAgent).getStaffAgent(StepXSequentialBehaviour.this.agentName));
					this.myAgent.send(message);
					this.state++;
					break;
				case 1:
					final MessageTemplate tpl = MessageTemplate.and(
							MessageTemplate
									.MatchPerformative(ACLMessage.INFORM),
							MessageTemplate
									.MatchConversationId(Data.GETITEMS));
					message = this.myAgent.receive(tpl);
					if (message != null) {
						System.out.println("StudioAgent --> Receive from StaffAgents");
						// UPDATE MODEL
						final HashMap<String, Integer> map = ((StudioAgent)myAgent).deserializeItems(message
								.getContent());
						((StudioAgent)myAgent).getCurrentGame()
								.setLvlCreativity(((StudioAgent)myAgent).getCurrentGame()
										.getLvlCreativity()
										+ map.get(Data.CREATIVITYITEM));
						((StudioAgent)myAgent).getCurrentGame()
								.setLvlGameplay(((StudioAgent)myAgent).getCurrentGame()
										.getLvlGameplay()
										+ map.get(Data.GAMEPLAYITEM));
						((StudioAgent)myAgent).getCurrentGame()
								.setLvlGraphism(((StudioAgent)myAgent).getCurrentGame()
										.getLvlGraphism()
										+ map.get(Data.GRAPHISMITEM));
						((StudioAgent)myAgent).getCurrentGame()
								.setLvlSound(((StudioAgent)myAgent).getCurrentGame()
										.getLvlSound()
										+ map.get(Data.SOUNDITEM));

						// SEND 2 VIEW
						ACLMessage reply = new ACLMessage(ACLMessage.INFORM);
						reply.setConversationId(StepXSequentialBehaviour.this.step);
						reply.setContent(message.getContent());
						reply.addReceiver(((StudioAgent)myAgent).getXCommandAgent());
						this.myAgent.send(reply);

						reply = new ACLMessage(ACLMessage.INFORM);
						reply.setConversationId(Data.UPDATEPROGRESS);
						reply.setContent(((StudioAgent)myAgent).serializeItems(
								((StudioAgent)myAgent).getCurrentGame()
										.getLvlGameplay(),
										((StudioAgent)myAgent).getCurrentGame()
										.getLvlGraphism(),
										((StudioAgent)myAgent).getCurrentGame().getLvlSound(),
										((StudioAgent)myAgent).getCurrentGame()
										.getLvlCreativity()));
						reply.addReceiver(((StudioAgent)myAgent).getXAgent());
						this.myAgent.send(reply);
						this.state++;
					} else {
						block();
					}
					break;
				}

			}

			@Override
			public boolean done() {
				return this.state == 2;
			}
		}

	}

	public StepXSequentialBehaviour(final Agent a, final String step) {
		super(a);
		this.step = step;
		this.addSubBehaviour(new StepXInitBehaviour());
		this.addSubBehaviour(new StepExchangeBehaviour(a, 1000));
	}

}
